module main(
	// System
	Clk,
	Rst_n,
	
	// Uart
	uart_tx,
	uart_rx,
	
	// Key
	Key0,
	Key1,
	Key2,
	
	// LED
	Led0,
	Led1,
	Led2,
	Led3,

	// TFT
	TFT_RGB,
	TFT_HS,
	TFT_VS,
	TFT_CLK,
	TFT_DE,
	TFT_PWM
);
	// System
	input Clk;
	input Rst_n;
	
	// Uart
	output uart_tx;
	input uart_rx;
	
	// Key
	input Key0;
	input Key1;
	input Key2;	
	
	// Led
	output Led0;
	output Led1;
	output Led2;
	output Led3;
	
	// tft output
	output TFT_HS;
	output TFT_VS;
	output TFT_CLK;
	output TFT_DE;
	output TFT_PWM;
	output [15:0]TFT_RGB;
	
	// 接收逻辑
	wire [8:0] rx_data;
	wire rx_done;
	reg [1:0] bps_setting;
	reg [1:0] check_setting;
	
	// 发送逻辑
	reg [8:0] tx_data;
	reg send_en;
	wire uart_state;
	
	// tft ram
	reg ram_wren;
	reg [11:0]ram_wraddress;
	reg [7:0]ram_data;
	
	reg [11:0]receive_pos;
		
	// 按键状态
	wire Key0_p; 
	wire Key1_p; 
	wire Key2_p; 
	
	
	// 界面状态机
	reg system_state;
	reg [1:0] option;
	
	assign Led0 = system_state;
	assign Led1 = option[1];
	assign Led2 = option[0];
	
	// 更改配置项信号
	reg option_change;
	
	// 配置刷新
	reg flush_setting;
	reg [2:0]flush_setting_cnt;
	
	wire tx_done;
	
	// reg Debug;
	// assign Led3 = Debug;
	
	assign Led3 = option_change;
	
	button button_instance0(
		.clk(Clk) 			,
		.rst_n(Rst_n)			,
		.key(Key0)			,
		// key_r_flag  ,
		.key_p_flag(Key0_p)		// Key0检测按下标志	
	);  
	
	button button_instance1(
		.clk(Clk) 			,
		.rst_n(Rst_n)			,
		.key(Key1)			,
		// key_r_flag  ,
		.key_p_flag(Key1_p)		// Key1检测按下标志	
	);  
	
	button button_instance2(
		.clk(Clk) 			,
		.rst_n(Rst_n)			,
		.key(Key2)			,
		// key_r_flag  ,
		.key_p_flag(Key2_p)		// Key2检测按下标志	
	);  
	
	// 接收逻辑 不动
	uart_byte_rx uart_byte_rx_instance0(
		.clk(Clk),			   // 时钟发生器：system 50MHz
		.rst_n(Rst_n), 			// 复位使能：reg
		.uart_rx(uart_rx),		   // 串口接受线: system
		.bps_setting(bps_setting), 	// 波特率：reg 
		.check_setting(check_setting), // 校验方式: reg
		.data(rx_data),			   // 数据: reg
		.rx_done(rx_done)   		// 一次接收数据完成标志
	);
	
	
	uart_byte_tx uart_byte_tx_instance0(
		.clk(Clk),			   // 时钟发生器：system 50MHz
		.data(tx_data),			   // 数据: reg
		.send_en(send_en),  	   // 使能: reg
		.bps_setting(bps_setting), 	// 波特率：reg 
		.check_setting(check_setting), // 校验方式: reg
		.rst_n(Rst_n), 			// 复位使能：reg
		
		.uart_tx(uart_tx),		   // 串口发送线: system
		.tx_done(tx_done),   		// 一次发送数据完成标志
		.uart_state(uart_state)		// 发送数据状态，发送过程中为1，其它时候为0
	);
	
	vision_ctrl vision_ctrl_instance0(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.TFT_RGB(TFT_RGB),//TFT数据输出
		.TFT_HS(TFT_HS),	//TFT行同步信号
		.TFT_VS(TFT_VS),	//TFT场同步信号
		.TFT_CLK(TFT_CLK),
		.TFT_DE(TFT_DE),
		.TFT_PWM(TFT_PWM),
		// RAM 写
		.ram_wren(ram_wren),
		.ram_wraddress(ram_wraddress),
		.ram_input(ram_data)
	);
	
	// 按键切换状态逻辑
	always @(posedge Clk or negedge Rst_n)
	begin
		if (!Rst_n)
			system_state <= 0;
		else
			begin
				if(system_state == 0 && Key0_p == 1)
					system_state <= 1;
				else if(system_state == 1 && Key2_p == 1)
					system_state <= 0;
			end
	end
	
	// 正常状态按键1重置配置
	always @(posedge Clk or negedge Rst_n)
	begin 
		if (!Rst_n)
				flush_setting <= 1;
		else
			begin
				if (system_state == 0 && Key1_p == 1) // 正常状态,按键1重置配置
					flush_setting <= 1;
				else
					flush_setting <= 0;
			end
	end
	
	
	// 状态1下
	always @(posedge Clk or negedge Rst_n)
	begin 
		if (!Rst_n)
				option_change <= 0;
		else 
			begin
			if (system_state == 1)
				begin
					if(Key0_p == 1)    // 选择配置项
						begin
							if (option + 1 > 2)
								option <= 0;
							else
								option <= option + 1;
						end
					else if(Key1_p == 1) 	// 更改配置项
							option_change <= 1;
					else
						option_change <= 0;
				end
			else
				begin
					option_change <= 0;
					option <= 0;
				end
			end
	end
	
	
	// 接收逻辑
	always @(posedge Clk or negedge Rst_n)
	begin
		if (!Rst_n)
				receive_pos <= 12'd81;
		else
			begin
				if (rx_done == 1)
					begin
					if (receive_pos == 2159)
						receive_pos <= 12'd81;
					else if ((receive_pos + 1) % 80 == 0)
						begin 
							receive_pos <= receive_pos + 2;
						end
					else if (receive_pos % 80 == 0)
						begin 
							receive_pos <= receive_pos + 1;
						end
					else
						receive_pos <= receive_pos + 1;
					end
				else 
					receive_pos <= receive_pos;
			end
	end
	
	
	// ram写逻辑
	always @(posedge Clk or negedge Rst_n)
	begin
	if (!Rst_n)
		begin
			ram_wren <= 1'b0;
			flush_setting_cnt <= 3'd7;
		end
	else
	begin
		if (rx_done == 1) // 有接收数据信号，刷新接收区域显存
			begin 
				ram_wren <= 1'b1;
				ram_data <= rx_data;
				ram_wraddress <= receive_pos;
			end
		else // 没有接收数据信号，刷新配置区域数据
			begin
			case (flush_setting_cnt)
			0:begin
					ram_wren <= 1'b0;
					flush_setting_cnt <= 3'd7;
			  end
			1:begin // 刷新send_setting配置
					ram_data <= tx_data;
					ram_wraddress <= 12'd2248;
					flush_setting_cnt <= 3'd0;
			  end
			2:begin // 刷新bps_setting eg. 115200 1
					flush_setting_cnt <= 3'd1;
					ram_wraddress <= 12'd2259;
					begin
						case (bps_setting)
							0: ram_data <= 8'd49;
							1: ram_data <= 8'd0;
							2: ram_data <= 8'd0;
							default: ram_data <= 8'd49;
						endcase
					end
			  end
			3:begin // 刷新bps_setting eg. 115200 1
					flush_setting_cnt <= 3'd2;
					ram_wraddress <= 12'd2260;
					begin
						case (bps_setting)
							0: ram_data <= 8'd49;
							1: ram_data <= 8'd0;
							2: ram_data <= 8'd0;
							default: ram_data <= 8'd49;
						endcase
					end
			  end
			4:begin // 刷新bps_setting eg. 115200 5
					flush_setting_cnt <= 3'd3;
					ram_wraddress <= 12'd2261;
					begin
						case(bps_setting)
							0: ram_data <= 8'd53;
							1: ram_data <= 8'd57;
							2: ram_data <= 8'd52;
							default: ram_data <= 8'd53;
						endcase 
					end
			  end
			5:begin // 刷新bps_setting eg. 115200 2
					ram_wraddress <= 12'd2262;
					flush_setting_cnt <= 3'd4;
					begin
						case (bps_setting)
							0: ram_data <= 8'd50;
							1: ram_data <= 8'd54;
							2: ram_data <= 8'd56;
							default: ram_data <= 8'd50;
						endcase
					end
			  end
			6:begin
					ram_wraddress <= 12'd2275;
					flush_setting_cnt <= 3'd5;
					if (check_setting < 2) // 无校验
							ram_data <= 8'd148;
					else if(check_setting == 2) // 偶校验
							ram_data <= 8'd146;
					else    // 奇校验
							ram_data <= 8'd144;
			  end
			7:begin
					ram_wren <= 1'b1;
					ram_wraddress <= 12'd2276;
					flush_setting_cnt <= 3'd6;
					if (check_setting < 2) // 无校验
							ram_data <= 8'd149;
					else if(check_setting == 2) // 偶校验
							ram_data <=8'd147;
					else    // 奇校验
							ram_data <= 8'd145;
			  end
			endcase
			end
	end
	end
	
	
	// 发送逻辑 无误
	always @(posedge Clk)
	begin
		if (send_en == 0)
		begin
			if (Key2_p == 1 && system_state == 0)
				send_en <= 1'b1;
		end
		else
			send_en <= 1'b0;
	end
	
	
	
	// 选项配置
	always @(posedge Clk)
	begin
		if (flush_setting == 1) // 重置配置
			begin
				bps_setting <= 2'b0;  // 默认115200
				check_setting <= 1'b1; // 默认无校验
				tx_data <= 8'b0011_0000; // 默认发送字符0
			end
		else
			begin
			if(option_change == 1)
				begin
					case(option)
						0: begin // 修改发送字符配置项
								if (tx_data + 1 >= 8'b0111_1111)
									tx_data <= 8'd32;
								else 
									tx_data <= tx_data + 1;
							end
						1:	begin // 修改波特率配置项
								if (bps_setting + 1 > 2)
									bps_setting <= 0;
								else 
									bps_setting <= bps_setting + 1;
							end
						2:begin // 修改校验码配置项 0x=>无校验 10->偶校验 11->奇校验
								if (bps_setting == 0)
									check_setting <= 1;
								else if(bps_setting == 3)
									check_setting <= 1'b1;
								else
									check_setting <= check_setting + 1;
						  end
					endcase
				end
			end
	end
	
	
	

endmodule
